在撰寫 Laravel 的單元測試或整合測試時,我們常常會遇到以下情境:
有某個方法你「不想真的執行」,
而是希望它「假裝已執行並回傳你想要的結果」。
這時候就可以使用 Laravel 提供的 Mock 功能,模擬物件的行為,只回傳你指定的結果,不進行實際邏輯或資料庫操作。
假設我們的 Service 使用了 Repository,如下:
public function getUserList($employeeNo)
{
$userRepository = app(UserRepository::class);
$userList = $userRepository->get();
return $userList;
}
我們不想在這個測試中真的執行 UserRepository::get(),因為這個 Repository 的測試已經獨立完成了。
public function testGetUserList(): void
{
$expect = User::factory()->count(2)->make(); // 使用 make() 不寫入資料庫
$this->mock(UserRepository::class, function (MockInterface $mock) use ($expect) {
$mock->shouldReceive('get')
->with() // 沒有參數
->andReturn($expect); // 回傳你預期的結果
});
$result = $this->userService->getUserList('EMP001');
$this->assertEquals(2, $result->count()); // 建議把期望值放在前面
}
Mock 是 Laravel 測試中非常好用的工具,它幫助我們: